<?php
declare (strict_types = 1);

namespace app\api\controller;

use app\api\BaseController;
use app\api\model\OAuthPdo;
use OAuth2\GrantType\AuthorizationCode;
use OAuth2\GrantType\UserCredentials;
use OAuth2\Request;
use OAuth2\Response;
use OAuth2\Server;
use think\exception\HttpException;

class Oauth extends BaseController
{
    public function authorize($redirect_uri, $client_id, $response_type, $state)
    {
        if (request()->isGet()) {
            return view('authorize');
        }

        $mysql = config('database.connections.mysql');
        $dsn   = "mysql:dbname={$mysql['database']};host={$mysql['hostname']}";

        $storage = new OAuthPdo([
            'dsn' => $dsn,
            'username' => $mysql['username'],
            'password' => $mysql['password']
        ]);

        // Pass a storage object or array of storage objects to the OAuth2 server class
        $server = new Server($storage, ['auth_code_lifetime' => config('database.auth_code_lifetime')]);

        $request = Request::createFromGlobals();
        $response = new Response();
        $userGrant = new UserCredentials($storage);

        if (!$userGrant->validateRequest($request, $response)) {
            throw new HttpException(400, $response->getParameter('error_description'));
        }

        $user_id = $userGrant->getUserId();

        $server->handleAuthorizeRequest($request, $response, true, $user_id);

        if (!($response->isSuccessful() || $response->isRedirection())) {
            throw new HttpException(400, $response->getParameter('error_description'));
        }

        return $response->send();
    }

    public function token()
    {
        $mysql = config('database.connections.mysql');
        $dsn   = "mysql:dbname={$mysql['database']};host={$mysql['hostname']}";

        $storage = new OAuthPdo([
            'dsn' => $dsn,
            'username' => $mysql['username'],
            'password' => $mysql['password']
        ]);

        $server = new Server($storage);
        $request = Request::createFromGlobals();
        $response = new Response();

        $server->handleTokenRequest($request, $response);

        return $response->send();
    }

}